package com.bdqn.qnnews.gateway.admin.filter;

import cn.hutool.json.JSONUtil;
import com.alibaba.nacos.common.utils.StringUtils;
import com.bdqn.qnnews.admin.api.dto.AdAdminDto;
import com.bdqn.qnnews.common.base.R;
import com.bdqn.qnnews.common.base.ResultCode;
import com.bdqn.qnnews.jwt.pojo.TokenPayLoad;
import com.bdqn.qnnews.jwt.utils.JwtTokenUtil;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * 管理平台统一鉴权过滤器
 * @author xlzhang
 */
@Component
public class AdminAuthorizeFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //获取请求和响应
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();

        //获取请求路径
        //  /login/in
        String uri = request.getURI().getPath();
        //判断该请求是否为登录请求
        if(uri.contains("/login")){
            //直接放行
            return chain.filter(exchange);
        }

        //获取token请求头，前端会固定以token这个字符串作为header头发送token令牌字符串
        String token = request.getHeaders().getFirst("token");
        // 设置响应头
        response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
        if(StringUtils.isEmpty(token)){
            //为空代表不合法，返回401
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            final String errorJson = JSONUtil.toJsonStr(R.error(ResultCode.TOKEN_REQUIRE));
            final DataBufferFactory dataBufferFactory = response.bufferFactory();
            //终止请求,响应异常数据
            return response.writeWith(Mono.fromSupplier(()-> dataBufferFactory.wrap(errorJson.getBytes())));
        }

        //获取公钥
        try {
            // 解析Token
            TokenPayLoad tokenPayLoad = JwtTokenUtil.verifyTokenByRsa(token);
            // 获取当前登录用户名
            String userJson = tokenPayLoad.getSub();
            //取出登录用户ID
            final AdAdminDto adUserDto = JSONUtil.toBean(userJson, AdAdminDto.class);

            //存入请求头
            request.mutate().header("userId",adUserDto.getId().toString());
            //放行
            return chain.filter(exchange);
        } catch (Exception e) {
            //为空代表不合法，返回401
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            final String errorJson = JSONUtil.toJsonStr(R.error(e.getMessage(),51));
            final DataBufferFactory dataBufferFactory = response.bufferFactory();

            //终止请求,响应异常数据
            return response.writeWith(Mono.fromSupplier(()-> dataBufferFactory.wrap(errorJson.getBytes())));
        }
    }

    /**
     * 数值越大，优先级越低
     * @return
     */
    @Override
    public int getOrder() {
        return 0;
    }
}